package edu.pku.sei.modeler.figures;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.PolylineDecoration;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.swt.SWT;

public class AssociationFigure extends PolylineConnection {
	/**
	 * the end of the association is navigable so this is an arrow.
	 */
	public static final int navigable=0;
	
	/**
	 * the end of the association is an aggregation i.e. this a translucide diamond.
	 */
	public static final int aggregation=1;
	
	/**
	 * the end of the association is a composition so this a black diamond.
	 */
	public static final int composition=2;
	
	/**
	 * the end of teh association is not navigable so there is nothing.
	 */
	public static final int nothing=3;


	
	/**
	 * create an association figure.
	 * 
	 * @param targetType the type of end of the association {@link AssociationFigure#navigable}
	 * @param sourceType the type of end of the association {@link AssociationFigure#navigable}
	 */
	public AssociationFigure(int sourceType, int targetType ) {
		super();
		this.setEnd(sourceType, targetType);
		
		}

	/**
	 * @{inheritDoc}
	 */
	@Override
	public void paintFigure(Graphics graphics) {
		graphics.pushState();
		graphics.setAntialias(SWT.ON);
		super.paintFigure(graphics);

//		if (this.img!=null){ // display an icon??
//		super.FillFigure(graphics);}
		graphics.popState();
	}

	/**
	 * used to display end of the association.
	 * @param targetType the type of end of the association {@link AssociationFigure#navigable}
	 * @param sourceType the type of end of the association {@link AssociationFigure#navigable}
	 */
	public void setEnd(int sourceType, int targetType ) {
		PolylineDecoration dec;
		PolygonDecoration decoration;
		PointList decorationPointList;

		//display end link near of the source
		switch(sourceType){
		case navigable: //its only navigable
			dec=new PolylineDecoration();
			dec.setScale( 15, 5);
			dec.setLineWidth(1);
			this.setSourceDecoration(dec); // arrow at target endpoint
			break;

		case aggregation: // this is aggregation
			decoration = new PolygonDecoration();
			decorationPointList= new PointList();
			decorationPointList.addPoint(0,0);
			decorationPointList.addPoint(-2,2);
			decorationPointList.addPoint(-4,0);
			decorationPointList.addPoint(-2,-2);
			decoration.setTemplate(decorationPointList);
			decoration.setBackgroundColor(ColorConstants.white);
			decoration.setScale(3, 3);
			this.setSourceDecoration(decoration);
			break;
		case composition: //this a compostion
			decoration = new PolygonDecoration();
			decorationPointList = new PointList();
			decorationPointList.addPoint(0,0);
			decorationPointList.addPoint(-2,2);
			decorationPointList.addPoint(-4,0);
			decorationPointList.addPoint(-2,-2);
			decoration.setTemplate(decorationPointList);
			decoration.setScale(3, 3);
			this.setSourceDecoration(decoration);
			break;
		case nothing: //its only navigable
			
			this.setSourceDecoration(null); // arrow at target endpoint
			break;

		}
		switch(targetType){
		case navigable://navigation
			dec=new PolylineDecoration();
			dec.setScale( 15, 5);
			dec.setLineWidth(1);
			this.setTargetDecoration(dec); // arrow at target endpoint
			break;


		case aggregation://aggregation
			decoration = new PolygonDecoration();
			decorationPointList= new PointList();
			decorationPointList.addPoint(0,0);
			decorationPointList.addPoint(-2,2);
			decorationPointList.addPoint(-4,0);
			decorationPointList.addPoint(-2,-2);
			decoration.setTemplate(decorationPointList);
			decoration.setBackgroundColor(ColorConstants.white);
			decoration.setScale(3, 3);
			this.setTargetDecoration(decoration);
			break;
		case composition://composition
			decoration = new PolygonDecoration();
			decorationPointList = new PointList();
			decorationPointList.addPoint(0,0);
			decorationPointList.addPoint(-2,2);
			decorationPointList.addPoint(-4,0);
			decorationPointList.addPoint(-2,-2);
			decoration.setScale(3, 3);
			decoration.setTemplate(decorationPointList);
			this.setTargetDecoration(decoration);
			break;
	case nothing: //its only navigable
			
			this.setTargetDecoration(null); // arrow at target endpoint
			break;
		}


	}
}

